package com.cskaoyan.service;

import com.cskaoyan.bean.User;
import com.cskaoyan.bean.mini_program_coupon.CouponBO;
import com.cskaoyan.bean.mini_program_coupon.CouponPOJO;
import com.cskaoyan.bean.mini_program_coupon.CouponUserPOJO;
import com.cskaoyan.bean.mini_program_coupon.CouponVO;
import com.cskaoyan.mapper.CartMapper;
import com.cskaoyan.mapper.MiniProgramCouponMapper;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/*
 * @author 魏骏杰
 */
@Service
public class MiniProgramCouponServiceImpl implements MiniProgramCouponService {
    @Autowired
    MiniProgramCouponMapper miniProgramCouponMapper;

    @Autowired
    CartMapper cartMapper;

    @Override
    public List<CouponVO> selectCouponListByUsername(CouponBO couponBO) {
        List<CouponPOJO> pojoList = miniProgramCouponMapper.findCurrentUsersCouponList(couponBO);
        List<CouponVO> list = new ArrayList<>();

        pojoList.forEach(couponPOJO -> list.add(CouponVO.getCouponVO(couponPOJO)));

        return list;
    }

    @Override
    public int exchangeNewCoupon(String code) {
        /*
        1. 存在兑换码对应的优惠券且该优惠券未被兑换
        2. 不存在兑换码对应的优惠券
        3. 存在兑换码对应的优惠券但该优惠券已达到兑换次数上限
         */

        CouponUserPOJO couponPOJO = miniProgramCouponMapper.selectExchangeCodeHasCorrespondingCoupon(code);

        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal();
        String name = currentUser.getUsername();

        if (couponPOJO == null) return -1;
        Integer id = miniProgramCouponMapper.selectUserIdByName(name);
        couponPOJO.setHasExchange(miniProgramCouponMapper.selectUserHasExchanged(id, couponPOJO.getCoupon_id()));
        if (couponPOJO.getLimit() == 1 && couponPOJO.getHasExchange() != 0) return -2;
        couponPOJO.setUser_id(id);

        if (couponPOJO.getTime_type() == 0) {
            couponPOJO.setUsed_time(DateCalculationUtil.getUsedTimeByDays(couponPOJO.getDays()));
            couponPOJO.setStart_time(DateCalculationUtil.getCurrentTime());
            couponPOJO.setEnd_time(DateCalculationUtil.getAfterSeveralDaysTime(couponPOJO.getDays()));
        } else {
            long startTime = couponPOJO.getStart_time().getTime();
            long endTime = couponPOJO.getEnd_time().getTime();
            couponPOJO.setUsed_time(DateCalculationUtil.getUserTimeByApartTime(startTime, endTime));
        }
        return couponPOJO.getLimit() != null ? miniProgramCouponMapper.insertCouponToTableUser(couponPOJO) : -2;
    }

    @Override
    public List<CouponVO> findAllAvailableCouponsList(CouponBO couponBO) {
        List<CouponPOJO> pojoList = miniProgramCouponMapper.findAllAvailableCouponsList(couponBO);
        List<CouponVO> list = new ArrayList<>();

        pojoList.forEach(couponPOJO -> list.add(CouponVO.getCouponVO(couponPOJO)));

        return list;
    }

    @Override
    public int receiveCouponByCouponId(CouponBO couponBO) {
        //获取当前用户
        Subject subject = SecurityUtils.getSubject();
        User currentUser = (User) subject.getPrincipal();
        String name = currentUser.getUsername();
        Integer id = miniProgramCouponMapper.selectUserIdByName(name);

        CouponPOJO couponPOJO = miniProgramCouponMapper.selectReceiveCouponByCouponId(couponBO);

        if (couponPOJO == null) return -1;
        if (couponPOJO.getType() == 2) return -3;

        CouponUserPOJO user = new CouponUserPOJO();

        user.setUser_id(id);
        user.setCoupon_id(couponPOJO.getCoupon_id());
        user.setDays(couponPOJO.getDays());
        user.setStatus(0);
        user.setUsed_time(DateCalculationUtil.getUsedTimeByDays(couponPOJO.getDays()));
        user.setStart_time(DateCalculationUtil.getCurrentTime());
        user.setEnd_time(DateCalculationUtil.getAfterSeveralDaysTime(couponPOJO.getDays()));

        if (couponPOJO.getLimit() == 1) {
            Integer hasReceive = miniProgramCouponMapper.selectUserHasExchanged(id, couponBO.getCouponId());
            if (hasReceive != 0) return -2;
        }

        return miniProgramCouponMapper.insertCouponToTableUser(user);
    }

    @Override
    public List<CouponVO> selectCouponListWhichCanBeAllowedUse(CouponBO couponBO) {
        List<Integer> cartId = new ArrayList<>();
        //通过购物车打开选择优惠券列表时，cartId=0，通过直接购买打开时则会传入参数
        if (couponBO.getCartId() == 0) {
            //通过username获取userid，通过userid查询cart表中checked字段值为1的购物车
            Subject subject = SecurityUtils.getSubject();
            User principal = (User) subject.getPrincipal();
            cartId = miniProgramCouponMapper.selectCartIdForChooseCoupons(principal.getUsername());
        } else {
            cartId.add(couponBO.getCartId());
        }
        couponBO.setCartIds(cartId);
        couponBO.setCurrentTime(DateCalculationUtil.getCurrentTime());

        List<CouponPOJO> pojoList = miniProgramCouponMapper.selectCouponsWhichPriceInRange(couponBO);
        List<CouponVO> list = new ArrayList<>();

        pojoList.forEach(couponPOJO -> {
            CouponVO couponVO = CouponVO.getCouponVO(couponPOJO);
            couponVO.setAvailable(true);
            list.add(couponVO);
        });

        return list;
    }


    private static class DateCalculationUtil {
        static Date getUsedTimeByDays(long days) {
            return new Date(days * 24 * 60 * 60 * 1000);
        }

        static Date getCurrentTime() {
            return new Date();
        }

        static Date getAfterSeveralDaysTime(long days) {
            return new Date(new Date().getTime() + days * 24 * 60 * 60 * 1000);
        }

        static Date getUserTimeByApartTime(long startTime, long endTime) {
            return new Date(endTime - startTime);
        }
    }
}
